Release 10.1A: OpenEdge Development:
Progress Dynamics Advanced Development


Initializing SmartObjects

You start a SmartObject application in two major steps. Creating the object instance is the first of those steps. This section describes the second step.

Once createobjects is done, the window publishes initializeObject, which cascades down as an event to all its children (and their children if any, recursively) and then initializes the window itself, as shown:

Procedure initializeObject: 
  Parameters:  <none> 
Candidate for: localization 
  Application code often must extend what happens at startup by localizing the 
initializeObject procedure. If your code is creating objects the framework 
doesn’t manage for you, then the code will also need to run initializeObject 
in them. 

Each type of SmartObject does its own initialization, and then passes control up the stack of super procedures with a RUN SUPER. Among the major events that happen along the way are described in the sections that follow.

The initialization runs enableObject unless it is instructed not to, that is, unless the DisableOnInit property is set to TRUE, which is not its default. It then runs viewObject unless instructed not to by setting the HideOnInit property, whose default value is also FALSE.

enableObject enables any handles in the SmartObject that are not associated with fields from an SDO (these could be extra developer-defined fill-in fields and so on). It sets the ObjectEnabled property to YES. It also runs the procedure enable_UI for AppBuilder-generated objects; this is not something you would write or change yourself. Its counterpart for disabling an object is the event procedure disableObject, as shown:

Procedure enableObject/disableObject: 
  Parameters: <none> 
  Candidate for: localization and calling 
    If there is extra work to do when the SmartObject is enabled or disabled, 
you can do this by creating a local version of the procedure. 
    If code needs to enable an object explicitly at the appropriate time, your 
code may run enableObject or disableObject directly. For example, enableObject 
must be run for an object by application code if its DisableOnInit Property 
was initially set to YES. 

The viewObject event procedure is actually run for every type of SmartObject, including nonvisual ones, since the concept of being viewed (which sets the ObjectHidden property to FALSE) is used essentially as a synonym for active for SmartObjects. For this reason it is supported for all SmartObjects, along with its counterpart, the procedure hideObject. The viewObject procedure actually views the object’s default frame if it has one, sets the ObjectHidden property to NO and publishes the linkState event with a parameter of active to signal to other objects, such as SmartPanels and toolbars, that they are now active (so buttons should be enabled that were disabled when the target object was hidden by hideObject, and linkState was published with inactive), as shown:

Procedure viewObject/hideObject: 
  Parameters: <none> 
  Candidate for localization and calling  
   If there is extra work to do when the SmartObject is viewed or hidden, you 
could write a local override of the procedure. 
   If code needs to view or hide an object explicitly at the appropriate time, 
then your code could run the procedure directly. For example, viewObject must 
be run for an object by application code if its HideOnInit Property was 
initially set to YES. 

The initialization sequence then runs displayobjects to display any nondatabase fields that can be defined. The displayobjects event procedure displays the values of any fields or other basic objects in a visual SmartObject that are not associated with SDO fields. It is run here during initialization, as shown:

Procedure displayobjects: 
  Parameters: <none> 
  Candidate for calling 
   If the values of non-data fields need be refreshed other than when a record 
is 
displayed in the object, then your code might call displayobjects to do this. 

The initialization sequence then runs enableFields, if appropriate (if there is a TableIO-Source in Save mode, which allows updates to be entered into the viewer’s fields at any time). Then it runs dataAvailable to see if there is a row in the Data-Source waiting to be displayed.

The enableFields event procedure enables those viewer fields or browser columns that are associated with SDO data fields (using the EnabledHandles property), setting their SENSITIVE attribute to YES. (Editors have their READ-ONLY attribute set to NO; they are always left SENSITIVE to allow them to be scrolled.) The FieldsEnabled property is set to YES, and the enableFields event is published to send it on to any contained SmartObjects.

The counterpart to enableFields for disabling data fields is the event procedure disableFields, as shown:

Procedure enableFields/disableFields: 
  Parameters: <none> 
  Candidate for: localization and calling 
    If additional code is needed for an object each time its fields are enabled 
or disabled, you could create a local version of the procedure. 
    If data-related fields need to be enabled or disabled when it doesn’t happen  
by default, then code could call the enable or disable procedure directly. 

The dataAvailable event procedure is run each time a new (different) row is positioned to in the SDO query, and when an Update completes. In the case of initializeObject, it is run to catch the case where the Data-Source might have been initialized first and has already published the event before the viewer was ready to. For visual SmartObjects it causes the field values for the newly selected row to be displayed.

For data objects, such as SDOs, it is passed on to a child SDO in a parent-child (master-detail) relationship when the parent SDO moves to a different row. In this case it causes the child SDO’s query to be re-prepared with the foreign key values from the parent row, and the query to be reopened, as shown:

Procedure dataAvailable: 
  Parameters: pcRelative AS CHARACTER 
Candidate for: localization 
    If additional code is needed for an object each time a different row is 
    Selected, this could be done in a local version of dataAvailable. 

The pcRelative parameter to dataAvailable can have these values:

The openQuery function opens the database query and populates the SDO’s RowObject temp-table with the first batch of rows from the database. First it runs the closeQuery function if the query has previously been opened. Then it runs the prepareQuery function to re-prepare the query if the QueryString property has been set (described in a later section). If the SDO is divided between client and AppServer, the client side invokes openQuery on the server to open the actual database query.

It then runs the fetchFirst procedure to populate the temp-table and position to the first row. fetchFirst runs the sendRows procedure, which has both a client and server version, to request the first batch of rows.

Finally, fetchFirst on the client side sets the QueryPosition property to FIRST and then publishes the dataAvailable event with an argument of FIRST to cause client-side objects to display the first row, as shown:

Function openQuery: 
  Parameters: <none> 
  Candidate for: calling 
    If the application has prepared a new query definition with a different 
where clause, or if the application wants to refresh the current query with 
the latest data, then code can call openQuery directly. 

The closeQuery function closes both the (client-side) RowObject temp-table query, emptying the temp-table, and also the (server-side) database query. It publishes dataAvailable to cause any Data-Targets to erase the current record display (or to close a dependent query if there is one). Your code does not normally call closeQuery directly.

The prepareQuery function prepares a new query if it has been modified by the functions used to change the where clause. It is intended to be run only internally on the server. Developers should use the functions described in the section on customizing queries, which in turn invoke this function at the proper time.

The fetchFirst procedure, along with fetchNext, fetchPrev, and fetchLast, repositions the RowObject query to the corresponding row. These procedures also request a new batch of rows from the database, if needed. They reset the QueryPosition property to the appropriate value (‘FirstRecord’, ‘LastRecord’, ‘OnlyRecord’, or ‘NotFirstOrLast’), and publish dataAvailable to alert other objects that there is a different row to display or open a dependent query with. As described, fetchFirst is run from openQuery.

Otherwise, the four procedures are normally published from a Navigation toolbar band when the corresponding navigation button is as shown:

Procedure fetchFirst/fetchNext/fetchPrev/fetchLast: 
  Parameters: <none> 
  Candidate for: calling 
   If repositioning other than from a toolbar is needed, then code could 
possibly run these procedures directly 

The sendRows procedure (along with its two subprocedures clientSendRows and serverSendRows) transfers batches of rows from server to client. Your code should not normally run this directly.

The dataAvailable procedure in a data display (Datavis) object such as a viewer or browser runs displayFields, which takes as its input parameter a list of values in the form returned by the colValues function, and moves them into the screen values of the viewer or browser. The displayFields procedure also runs displayobjects to display any nondata-related fields, as shown:

Procedure displayFields: 
  Parameters: pcValueList (CHR(1)-delimited list of values preceded by the 
RowIdent 
  Candidate for: localization 
    If application code needs to adjust values before they are displayed or 
do something else each time a row is displayed, you can do this in a local 
displayFields. 


Copyright © 2005 Progress Software Corporation
www.progress.com
Voice: (781) 280-4000
Fax: (781) 280-4095